package cn.js.sangu.unitStore.service;

import java.io.Serializable;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.hutool.core.util.StrUtil;
import cn.js.sangu.unitStore.common.config.MyAppConfig;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.dto.ResetPwdDTO;
import cn.js.sangu.unitStore.dto.TreeDataDTO;
import cn.js.sangu.unitStore.dto.UserDTO;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.mapper.UserMapper;
import cn.js.sangu.unitStore.service.process.UserComputerProcess;
import cn.js.sangu.unitStore.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 说明：
 * 作者：linshuo
 * 日期：2024/8/7 9:14
 */
@Slf4j
@Service
public class UserService extends ServiceImpl<UserMapper,User> {

    //IDEA不知道已在config配置了mapper路径，只知道mapper没有加注解，所以提示错误
//    @Autowired
//    UserMapper userMapper;

    //因继承了ServiceImpl并且指定了UserMapper,所以这里也不用声明了
    @Resource
    UserMapper userMapper;

    @Autowired
    MyAppConfig myAppConfig;

    @Autowired
    UserComputerProcess userComputerProcess;

//    @Value("${system.ip:localhost}")
//    String ip;

//    @Value("${server.port}")
//    String port;

//    @Value("${user.default-pwd:123456}")
//    String defaultPwd;

    String EX_MSG = "请联系管理员排查save接口:";

    public User save(UserDTO dto){
        User user = new User();
        BeanUtils.copyProperties(dto,user);
        if(StrUtil.isBlank(user.getAvatar())) user.setAvatar(myAppConfig.getHttps()+myAppConfig.getIp()+"/file/download/head.png");
        if (StrUtil.isBlank(user.getName())) user.setName(user.getUsername());
        if (StrUtil.isBlank(user.getPassword())) user.setPassword("121212");
        if (StrUtil.isBlank(user.getRole())) user.setRole("用户");

//        userMapper.sava(user);
//        if (!save(user)) return null; //保存失败返回空

        try {
            save(user);
        } catch (Exception e) {
//            e.printStackTrace();
            Throwable cause = e.getCause();
            if (cause instanceof DuplicateKeyException){
                System.out.println("");
                throw new ServiceException(EX_MSG+"重复密钥异常");
            }else if(cause instanceof SQLIntegrityConstraintViolationException){
                throw new ServiceException("用户名重复");
            } else {
                throw new ServiceException(EX_MSG+"异常实例未适配到");
            }
        }
        return user;
    }

    public void update(UserDTO dto){
        User user = new User();
        BeanUtils.copyProperties(dto,user);
//        userMapper.update(user);
        updateById(user);
    }


    @Override
    public boolean removeById(Serializable id) {
        this.cannotDelete(Arrays.asList(id));
        return super.removeById(id);
    }

    @Override
    public boolean removeBatchByIds(Collection<?> ids) {
        this.cannotDelete(ids);
        return super.removeBatchByIds(ids);
    }

    //不能删除当前正在登录的用户
    private void cannotDelete(Collection<?> ids){
        if (isCurrentUser(ids)) throw new ServiceException("不允许删除当前正在登录的用户");
    }

    //判断参数是否是当前登录用户
    private boolean isCurrentUser(Collection<?> ids){
        return ids.contains(Objects.requireNonNull(TokenUtils.getCurrentUser()).getId());
    }

    /**
     * 重置密码
     * @param dto
     */
    public void resetPwd(ResetPwdDTO dto){
        //参数都不能为空
        if (StrUtil.isBlank(dto.getUsername()) || StrUtil.isBlank(dto.getPassword()) || StrUtil.isBlank(dto.getNewPwd()) || StrUtil.isBlank(dto.getNewPwd2())){
            throw new ServiceException("用户名和密码不完整");
        }
        if (!dto.getNewPwd().equals(dto.getNewPwd2())){
            throw new ServiceException("两次新密码不一致");
        }
        //前端可能会优先传Id
//        User user = userMapper.findById(dto.getId());
        User user = userMapper.selectById(dto.getId());
        if (null == user){
//            List<User> userList = userMapper.findByUserName(dto.getUsername());
            User dbUser = this.findByUserName(dto.getUsername());
//            if (userList.size()>0){
//                user = userList.get(0);
//            }else {
//                throw new ServiceException("用户名不存在");
//            }
            if (null == dbUser){
                throw new ServiceException("用户名不存在");
            }
        }
        // assert user != null;
        // 检查 user 是否为 null，避免空指针异常
        if (user != null && !dto.getPassword().equals(user.getPassword())){
            throw new ServiceException("原始密码错误");
        }
        if (user != null) {
            user.setPassword(dto.getNewPwd());
        } else {
            throw new ServiceException("用户对象为空，无法重置密码");
        }
//        userMapper.update(user);
        updateById(user);
    }
    /**
     * 忘记密码：根基手机号重置密码
     * @param dto
     */
    public void forgetPwd(ResetPwdDTO dto){
        //所有参数都不能为空
        if (StrUtil.isBlank(dto.getUsername()) || StrUtil.isBlank(dto.getPhone())){
            throw new ServiceException("用户名和手机号不完整");
        }
//        User user;
//        List<User> userList = userMapper.findByUserName(dto.getUsername());
        User user = this.findByUserName(dto.getUsername());
//        if (userList.size()>0){
//            user = userList.get(0);
//        }else {
//            throw new ServiceException("用户名不存在");
//        }
        if (null == user){
            throw new ServiceException("用户名不存在");
        }

        if (!dto.getPhone().equals(user.getPhone())) {
            throw new ServiceException("手机号不匹配");
        }
        //默认密码123456
        user.setPassword(myAppConfig.getDefaultPwd());
//        userMapper.update(user);
        updateById(user);
    }

//    public Integer delete(Integer id){
//        userMapper.delete(id);
//    }

//    public void deleteBatch(List<Integer> ids) {
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        for (Integer id : ids) {
//            userMapper.delete(id);
//        }
//    }

//    public List<User> findAll(){
//        return userMapper.findAll();
//    }
//
//    public User findById(Integer id){
//        return userMapper.findById(id);
//    }
//
//    public List<User> findByName(String name){
//        return userMapper.findByName(name);
//    }
//
//    public List<User> findByParam(String name){
//        return userMapper.findByParam(name);
//    }

//    public Page<User> findByPage(String name, Integer pageNum, Integer pageSize){
//        //第一次1-1*10=0，10；第二次2-1*10，10；第三次3-1*10=20，10；  从第20开始，向后查10个；
//        Integer skipNum = (pageNum-1)*pageSize;
//
//        List<User> list = userMapper.findByPage(name, skipNum, pageSize);
//        Integer count = userMapper.findCountByPage(name);
//
//        Page<User> page = new Page<>();
//        page.setList(list);
//        page.setTotal(count);//总数
//        return page;
//    }

   

    public User register(UserDTO dto) {
//        List<User> list = userMapper.findByUserName(dto.getUsername());
        User dbUser = this.findByUserName(dto.getUsername());
//        if (null!=list && 0!= list.size()){
//            throw new ServiceException("账号已存在，请换一个再试试");
//        }
        if (null != dbUser){
            throw new ServiceException("账号已存在，请换一个再试试");
        }

        dto.setName(dto.getUsername());
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setState(0); // 设置用户状态为未激活
        try {
            save(user);
        } catch (Exception e) {
            Throwable cause = e.getCause();
            if (cause instanceof DuplicateKeyException){
                throw new ServiceException(EX_MSG+"重复密钥异常");
            }else if(cause instanceof SQLIntegrityConstraintViolationException){
                throw new ServiceException("用户名重复");
            } else {
                throw new ServiceException(EX_MSG+"异常实例未适配到");
            }
        }
        return user;
    }

    public UserDTO login(UserDTO dto) {
//        List<User> list = userMapper.findByUserName(dto.getUsername());
        User user = this.findByUserName(dto.getUsername());
//        if (null == list || list.size()<0){
//            throw new ServiceException("账号不存在");
//        }
//        if (list.size()>1){
//            log.warn("用户名不唯一，请排查");
//            throw new ServiceException("用户名不唯一");
//        }
//        User user = list.get(0);

        if (null == user){
            throw new ServiceException("账号不存在");
        }
        if (!dto.getPassword().equals(user.getPassword())){
            throw new ServiceException("用户名或密码错误");
        }
        user.setState(1); // 设置用户状态为在线
        updateById(user);

        UserDTO res = new UserDTO();
        BeanUtils.copyProperties(user,res);
        res.setToken(TokenUtils.createToken(user.getId().toString(), user.getPassword()));
        return res;
    }

    /**
     * 用户退出登录方法，设置用户状态为已离线
     * @param userId 用户 ID
     */
    public void logout(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setState(2); // 设置用户状态为已离线
            updateById(user);
        }
    }

    //---------------封装-----------------------
    public User findByUserName(String username){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        return getOne(queryWrapper);
    }

    public List<TreeDataDTO> getSelect() {
        List<TreeDataDTO> resList = new ArrayList<>();
        List<User> list = userMapper.selectList(null);
        //当前登录用户带disable=true
        User currentUser = TokenUtils.getCurrentUser();
//        list.forEach( u -> resList.add(new TreeDataDTO(u.getId().toString(),u.getName(),u.getRole())));
        for (User user : list) {
            assert currentUser != null;
            resList.add(new TreeDataDTO(user.getId(),user.getName(),user.getRole(), user.getId().equals(currentUser.getId())));
        }
        return resList;

    }

    /**
     * 更新电脑状态
     * @param id 用户ID
     * @param status 新状态值 (1:在线, 2:离线)
     * @return 更新结果
     */
    public boolean updateComputerStatus(Integer id, Integer status) {
        if (id == null || status == null) {
            throw new ServiceException("参数不能为空");
        }
        
        if (status != 1 && status != 2) {
            throw new ServiceException("无效的状态值");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }

        // 检查当前状态是否与新状态相同
        if (user.getComputer().equals(status)) {
            throw new ServiceException("状态相同无需改变");
        }

        // Device device = new Device();
        // device.setUserId(id);
        // device.setComputer(status);
        // device.setAccount(user.getTAccount());
        // device.setPassword(user.getTPwd());
        // device.setDeviceName(user.getDeviceName());

        //调用第三方接口
        // userComputerProcess.ready(device);
        if (userComputerProcess.ready(user.getTAccount(),user.getTPwd(),user.getDeviceName(),status)) {
            // 构建更新条件
            LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(User::getId, id)
                .set(User::getComputer, status);
            return this.update(wrapper);
        }else {
            log.error("调用第三方接口失败");
            throw new ServiceException("调用三方接口返回失败");
        }
    }

    public boolean updateAllComputerStatus() {
        //查询所有用户
        List<User> userList = userMapper.selectList(null);
        if (userList.size()>0){
            for (User user : userList) {
                if (StrUtil.isNotBlank(user.getTAccount()) && StrUtil.isNotBlank(user.getTPwd()) && StrUtil.isNotBlank(user.getDeviceName())) {
                    Integer status = userComputerProcess.findStatus(user.getTAccount(),user.getTPwd(),user.getDeviceName());
                    if (status != null) {
                        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
                        wrapper.eq(User::getId, user.getId()).set(User::getComputer, status);
                        return this.update(wrapper);
                    } else {
                        // throw new ServiceException("获取电脑状态失败");
                        return false;
                    }
                }
            }
        }
        return false;
    }
}
